package com.example.demo;

import cn.hutool.core.date.StopWatch;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @auth:Easettle
 * @date:2024年07月26日 11:47
 * @describe:
 **/
@Slf4j
public class ExecutorBatch {


    private static final int BATCH_SIZE = 50; // 每批处理的数量

    // 创建一个通用的方法来初始化 Easettle 对象列表
    private List<Easettle> initEasettleList(int size) {
        List<Easettle> batchPayReqParams = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            Easettle billInfoPayDto = new Easettle();
            billInfoPayDto.setSource(new BigDecimal(i + 50));
            batchPayReqParams.add(billInfoPayDto);
        }
        return batchPayReqParams;
    }

    public void batchProcess() {
        StopWatch started = new StopWatch("batchProcess");
        started.start();
                List < Easettle > batchPayReqParams = initEasettleList(60);
        Map<String, Boolean> resultMap = new HashMap<>();
        ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

        final AtomicInteger index = new AtomicInteger(0);
        batchPayReqParams.forEach(param -> {
            int i = index.getAndIncrement();
            if (i % BATCH_SIZE == 0) {
                int endIndex = Math.min(i + BATCH_SIZE, batchPayReqParams.size());
                List<Easettle> assetBatchs = batchPayReqParams.subList(i, endIndex);
                String batchNo = UUID.randomUUID().toString().replace("-", "");
                executor.submit(() -> {
                    try {
                        log.info("推送的批次号:{},推送的数据:{}", batchNo, assetBatchs);
                        resultMap.put(batchNo, Boolean.TRUE);
                    } catch (Exception e) {
                        resultMap.put(batchNo, false);
                        log.error("推送数据异常: {}", e.getMessage());
                    }
                });
            }
        });

        executor.shutdown();
        try {
            if (!executor.awaitTermination(10, TimeUnit.MINUTES)) {
                executor.shutdownNow(); // 强制关闭线程池
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            log.error("等待线程池关闭时被中断: {}", e.getMessage());
        }
        started.stop();
        log.info("---推送应付耗时:{}:{}", started.currentTaskName(),started.getTotalTimeSeconds());

    }

    public void futureProcess() throws ExecutionException, InterruptedException {
        StopWatch started = new StopWatch("futureProcess");
        started.start();
        List<Easettle> batchPayReqParams = initEasettleList(60);
        ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

        final AtomicInteger index = new AtomicInteger(0);
        List<Future<Map<String, Boolean>>> futures = new ArrayList<>();
        batchPayReqParams.forEach(param -> {
            int i = index.getAndIncrement();
            if (i % BATCH_SIZE == 0) {
                int endIndex = Math.min(i + BATCH_SIZE, batchPayReqParams.size());
                List<Easettle> assetBatchs = batchPayReqParams.subList(i, endIndex);
                String batchNo = UUID.randomUUID().toString().replace("-", "");
                Callable<Map<String, Boolean>> callback = () -> commonParams(batchNo, assetBatchs);
                Future<Map<String, Boolean>> res = executor.submit(callback);
                futures.add(res);
            }
        });

        for (Future<Map<String, Boolean>> future : futures) {
            log.info("future 返回:{}", future.get());
        }

        executor.shutdown();
        try {
            if (!executor.awaitTermination(10, TimeUnit.MINUTES)) {
                executor.shutdownNow(); // 强制关闭线程池
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            log.error("等待线程池关闭时被中断: {}", e.getMessage());
        }
        started.stop();
        log.info("---推送应付耗时:{}:{}", started.currentTaskName(),started.getTotalTimeSeconds());
    }

    private Map<String, Boolean> commonParams(String batchNo, List<Easettle> assetBatchs) {
        Map<String, Boolean> resultMap = new HashMap<>();
        try {
            log.info("推送的批次号:{},推送的数据:{}", batchNo, assetBatchs);
            resultMap.put(batchNo, Boolean.TRUE);
        } catch (Exception e) {
            resultMap.put(batchNo, false);
            log.error("推送数据异常: {}", e.getMessage());
        }
        return resultMap;
    }




}
